using System;
using System.Reflection;

namespace WCSFContrib.Extensions.EventBroker
{
	/// <summary>
	/// A publisher container for an instance of a type and one of it's publication
	/// </summary>
	public class Publisher : EventBrokingData<EventInfo>
	{
		/// <summary>
		/// Creates an instace of a publication
		/// </summary>
		/// <param name="instance">Instance that publishes</param>
		/// <param name="topic">Topic that is published</param>
		/// <param name="eventInfo">Event which will be raised when the topic is published</param>
		public Publisher(object instance, string topic, EventInfo eventInfo)
			: base(instance, topic, eventInfo)
		{ }


		/// <summary>
		/// Creates an instace of a publication
		/// </summary>
		/// <param name="instance">Instance that publishes</param>
		/// <param name="memberTopicData">Topic that is published and event which will be raised when the topic is published</param>
		public Publisher(object instance, MemberReference<EventInfo> memberTopicData)
			: base(instance, memberTopicData)
		{ }

		/// <summary>
		/// The type of the event handler which handles the event.
		/// </summary>
		public Type EventHandlerType
		{
			get
			{
				return memberTopicData.Info.EventHandlerType;
			}
		}

		/// <summary>
		/// Add a delegate method to the publisher which will be called in the event of the event.
		/// </summary>
		/// <param name="delegate">Delegate to call</param>
		/// <returns>True if the addition was successful. False if the publisher is dead.</returns>
		public bool AddEventHandler(Delegate @delegate)
		{
			if (!IsAlive)
				return false;
			object target = Instance;
			MemberInfo.AddEventHandler(target, @delegate);
			return true;
		}

		/// <summary>
		/// Remove a delegate method from the publisher.
		/// </summary>
		/// <param name="delegate">Delegate to remove</param>
		/// <returns>True if the removal was successful. False if the publisher is dead.</returns>
		public bool RemoveEventHandler(Delegate @delegate)
		{
			if (!IsAlive)
				return false;
			object target = Instance;
			MemberInfo.RemoveEventHandler(target, @delegate);
			return true;
		}
	}
}